package com.wxxymakers.cklabrecruit.config;

import com.wxxymakers.cklabrecruit.utils.CacheUtils;
import io.github.biezhi.ome.OhMyEmail;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.EventListener;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConverterFactory;
import org.springframework.format.FormatterRegistry;
import org.springframework.util.StringUtils;
import org.springframework.web.context.support.ServletRequestHandledEvent;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @AUTHOR soft
 * @DATE 2018/11/15 0:13
 * @DESCRIBE
 */
@Slf4j
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

    private final CacheUtils cacheUtils;

    @Value("${email.account}")
    private String account;
    @Value("${email.pwd}")
    private String pwd;

    @Autowired
    public WebConfig(CacheUtils cacheUtils) {
        this.cacheUtils = cacheUtils;
    }

    @PostConstruct
    public void EmailInit()  {
        OhMyEmail.config(OhMyEmail.SMTP_QQ(false), account, pwd);
    }

    @EventListener(ServletRequestHandledEvent.class)
    public void requestEvent(ServletRequestHandledEvent event) {
        String url     = event.getRequestUrl();
        String method  = event.getMethod();
        String address = event.getClientAddress();
        int    status  = event.getStatusCode();
        if (status == 200) {
            log.info("from: {} {}: {} {}", address, method, url, status);
        } else {
            log.warn("from: {} {}: {} {}", address, method, url, status);
        }
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new HandlerInterceptorAdapter() {
            @Override
            public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                    throws Exception {
                String ip = request.getHeader("X-Forwarded-For");
                if (StringUtils.isEmpty(ip)) {
                    ip = request.getRemoteHost();
                }
                Integer o = (Integer) cacheUtils.get(ip);
                if (o == null) {
                    cacheUtils.put20(ip, 1);
                } else if (o < 5) {
                    cacheUtils.put20(ip, o + 1);
                } else { // 二十分钟内连续访问五次被禁
                    response.sendRedirect("/access");
                    return false;
                }
                return true;
            }
        }).addPathPatterns("/recruit/reapply", "/recruit/apply");
        super.addInterceptors(registry);
    }

    @Override
    public void addFormatters(FormatterRegistry registry) {
        ConverterFactory<String, Enum> converterFactory = new ConverterFactory<String, Enum>() {
            @Override
            public <T extends Enum> Converter<String, T> getConverter(Class<T> targetType) {
                return new Converter<String, T>() {
                    @Override
                    public T convert(String source) {
                        return (T) Enum.valueOf(targetType, source.trim().toUpperCase());
                    }
                };
            }
        };
        registry.addConverterFactory(converterFactory);
        super.addFormatters(registry);
    }
}
